package com.qire.antsbinder.dal;

import com.qire.antsbinder.DynamicProxyFactory.ProxyHandler;
import com.qire.antsbinder.dal.annotation.DataAccess;
import com.qire.antsbinder.dal.annotation.ParamsAlias;
import com.qire.antsbinder.dal.annotation.ParamsHead;
import com.qire.antsbinder.dal.annotation.ParamsUrl;
import com.qire.antsbinder.dal.annotation.ParamsWrap;
import com.qire.antsbinder.utils.TypeUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;

public abstract class AntsDataWarehouse extends DataWarehouse implements ProxyHandler {

    /**
     * 提取参数值
     * @param value 传递的原值
     * @param converterClass 转换器
     * @return 通过转换器转换后的值，如果为默认转换器，则保持原值
     */
    private Object takeValue(Object value, Class<? extends ParamsConverter> converterClass) {
        if(converterClass.equals(ParamsConverter.class)) {
            return value;
        } else {
            ParamsConverter paramsConverter = null;
            try {
                paramsConverter = converterClass.newInstance();
            } catch (IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
            }
            return paramsConverter.change(value);
        }
    }

    // 代理扩展行为
    @Override
    public boolean parse(Object proxy, Method method, Object[] args) {
        return method.isAnnotationPresent(DataAccess.class);
    }

    @Override
    public <T> T doHandle(Object proxy, Method method, Object[] args) {
        DataAccess dataAccess = method.getAnnotation(DataAccess.class);
        String url = dataAccess.url();
        MethodType methodType = dataAccess.methodType();
        WarehouseCacheMode cacheMode = dataAccess.cacheMode();
        long cacheTime = dataAccess.cacheTime();

        HashMap<String, Object> httpParams = new HashMap<>();

        List<? extends Annotation> parameterAnnotations = TypeUtils.findParameterAnnotationByType(method, ParamsWrap.class);
        if(parameterAnnotations != null) {
            int length = parameterAnnotations.size();
            for(int index = 0; index < length; index++) {
                Annotation annotation = parameterAnnotations.get(index);

                if(annotation instanceof ParamsAlias) {
                    ParamsAlias paramsAlias = (ParamsAlias) annotation;
                    httpParams.put(paramsAlias.name(), takeValue(args[index], paramsAlias.converter()));
                } else if(annotation instanceof ParamsUrl) {
                    url = String.valueOf(args[index]);
                } else if(annotation instanceof ParamsHead) {
                    ParamsHead paramsHead = (ParamsHead) annotation;
                }

            }
        }

//        Type resultType = method.getReturnType(); // 返回的是 CLASS ，Class 类型，在获取泛型事只能获得接口类型，泛型类型被擦除
        Type resultType = method.getGenericReturnType(); // 返回的是 Type，会包含泛型类型
        getData(url, httpParams, methodType, cacheMode, cacheTime, resultType);

        // 如果需要实现同步回传，可是使用2种方式：
        // 第一使用Future等待获取返回后回传，
        // 第二种使用异步对象返回，使用Type构建一个实体对象，立即返回，改Type定义必须继承Observer,实现通知回调方法。别再在这里完成绑定回调。则可以回调通知到具体对象

        return null;
    }

    @Override
    public void doBefore(Object proxy, Method method, Object[] args) {}

    @Override
    public void doAfter(Object proxy, Method method, Object[] args) {}

}
